home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
util
/
misc
/
2b_CAF.lha
/
caf
/
src
/
caf.c
Wrap
C/C++ Source or Header
|
1999-03-18
|
10KB
|
443 lines
/* CSAminet ver. 0.0.1 (13-Mar-99)
Copyright (C) 1999 Karol Bryd (kbryd@femina.com.pl)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <exec/memory.h>
#include <utility/tagitem.h>
#define BOLD "\033[1m"
#define NORMAL "\033[0m"
static char *ver[]={"$VER: CAF 1.0 (13-03-99)"};
static char archives_path[32];
static char tree_path[108];
static char temp_path[108];
static char command[255];
int simulate = FALSE;
char *stristr(char *buf, char *str)
{
register int len = strlen(buf);
register int len2 = strlen(str);
register int a;
for(a = 0; a <= len - len2; a++)
if(strnicmp(&buf[a], str, len2) == 0)
return(&buf[a]);
return(0);
}
int get_type(char *in, char *out, char *header)
{
int n = 0, i = 0;
char *h;
h = stristr(in, header);
if(h)
{
while(h[n] != ':')
n++;
n += 2;
while(1)
{
while(h[n] != 10)
out[i++] = h[n++];
if(h[n - 1] != ',')
break;
else
{
while(isspace(h[n++])) ;
n--;
}
}
out[i] = 0;
return(TRUE);
}
return(FALSE);
}
void check_for_dir(char *path_in)
{
BPTR lock;
lock = Lock(path_in, ACCESS_READ);
if(lock)
{
UnLock(lock);
return;
}
sprintf(command, "makedir >nil: %s", path_in);
system(command);
}
void copy_archive(char *src, char *dest, char *readme)
{
check_for_dir(dest);
sprintf(command, "c:copy >nil: %s %s", src, dest);
system(command);
printf(BOLD "Moved %s to %s\n" NORMAL, src, dest);
sprintf(command, "c:copy >nil: %s %s", readme, dest);
system(command);
if(!simulate)
{
char *ln;
sprintf(command, "c:delete >nil: %s QUIET", src);
system(command);
ln = strchr(src, '.');
if(ln)
*ln = 0;
sprintf(command, "c:delete >nil: %s.readme QUIET", src);
system(command);
}
}
char *scan_for_readme(char *start_dir)
{
char readme_path[255];
struct FileInfoBlock *fib;
BPTR lock;
fib = AllocDosObject(DOS_FIB, TAG_DONE);
if(!fib)
return(NULL);
lock = Lock(start_dir, ACCESS_READ);
bzero(readme_path, sizeof(readme_path));
Examine(lock, fib);
while(ExNext(lock, fib))
{
if(fib->fib_EntryType < -2)
{
if(astcsma(fib->fib_FileName, "#?.readme") != 0)
{
static char filename[108];
strcpy(filename, start_dir);
AddPart(filename, fib->fib_FileName, sizeof(filename));
FreeDosObject(DOS_FIB, fib);
UnLock(lock);
return(filename);
}
}
else if(fib->fib_EntryType == ST_USERDIR)
{
char *ret;
strcpy(readme_path, start_dir);
AddPart(readme_path, fib->fib_FileName, sizeof(readme_path));
if(ret = scan_for_readme(readme_path))
{
FreeDosObject(DOS_FIB, fib);
UnLock(lock);
return(ret);
}
}
}
FreeDosObject(DOS_FIB, fib);
UnLock(lock);
return(NULL);
}
void unlha_process(char *name, char *readme)
{
static char dest_name[108];
char temp_dir[108], full_name[108];
char rnd_name[32], type[32];
char *buf, *readme_name;
long size, broken = FALSE, correct_archive = FALSE;
BPTR fh, lock, old_dir;
strcpy(rnd_name, "CSA_XXXXXXXX");
mktemp(rnd_name);
strcpy(temp_dir, temp_path);
AddPart(temp_dir, rnd_name, 108);
lock = Lock(temp_path, ACCESS_READ);
if(!lock)
return;
old_dir = CurrentDir(lock);
UnLock(CreateDir(rnd_name));
CurrentDir(old_dir);
UnLock(lock);
strcpy(full_name, archives_path);
AddPart(full_name, name, 108);
sprintf(command, "lha >nil: -m -q x %s #?.readme %s/", full_name, temp_dir);
if(system(command) > 0)
broken = TRUE;
readme_name = scan_for_readme(temp_dir);
if(readme_name)
{
fh = Open(readme_name, MODE_OLDFILE);
if(fh)
{
Seek(fh, 0, OFFSET_END);
size = Seek(fh, 0, OFFSET_BEGINNING);
buf = AllocVec(size, MEMF_ANY);
if(buf)
{
Read(fh, buf, size);
if(get_type(buf, type, "Type:"))
correct_archive = TRUE;
FreeVec(buf);
}
Close(fh);
}
}
if(correct_archive)
{
if(broken)
{
strcpy(dest_name, tree_path);
AddPart(dest_name, "broken", sizeof(dest_name));
printf("Encountered damaged archive: \"%s\", moved to %s\n", name, dest_name);
}
else
{
strcpy(dest_name, tree_path);
AddPart(dest_name, stpblk(type), sizeof(dest_name));
}
copy_archive(name, dest_name, readme_name);
}
else
printf("Archive \"%s\" probably isn't from Aminet...Skipped.\n", name);
sprintf(command, "c:delete >nil: %s ALL QUIET", temp_dir);
system(command);
}
void process_file(char *name)
{
static char dest_name[108];
static char local_name[108];
char *ext, *buf, type[32];
long size;
BPTR fh;
strcpy(local_name, name);
ext = stristr(local_name, ".lha");
if(!ext)
return;
*ext = 0;
strcat(ext, ".readme");
fh = Open(local_name, MODE_OLDFILE);
if(!fh)
{
unlha_process(name, local_name);
return;
}
Seek(fh, 0, OFFSET_END);
size = Seek(fh, 0, OFFSET_BEGINNING);
buf = AllocVec(size, MEMF_ANY);
if(!buf)
{
Close(fh);
return;
}
Read(fh, buf, size);
Close(fh);
if(!(get_type(buf, type, "Type:")))
return;
FreeVec(buf);
strcpy(dest_name, tree_path);
AddPart(dest_name, stpblk(type), sizeof(dest_name));
copy_archive(name, dest_name, local_name);
}
int scan_dir(void)
{
struct FileInfoBlock *fib;
BPTR lock, fh;
lock = Lock(archives_path, ACCESS_READ);
if(!lock)
return(-1);
fib = AllocDosObject(DOS_FIB, TAG_DONE);
Examine(lock, fib);
while(ExNext(lock, fib))
{
if(fib->fib_EntryType < -2)
{
if(astcsma(fib->fib_FileName, "#?.lha") != 0)
process_file(fib->fib_FileName);
}
}
UnLock(lock);
FreeDosObject(DOS_FIB, fib);
}
void create_tree(void)
{
BPTR lock, fh, old_dir, initial_dir = 0;
char buf[32];
char path[108];
fh = Open("tree", MODE_OLDFILE);
if(!fh)
{
printf("No \"tree\" file in current directory!\n");
return;
}
bzero(path, sizeof(path));
lock = Lock(tree_path, ACCESS_READ);
old_dir = CurrentDir(lock);
while(FGets(fh, buf, sizeof(buf)))
{
char *white;
BPTR new_dir_lock;
white = strchr(buf, ' ');
if(white)
*white = 0;
strcpy(path, tree_path);
AddPart(path, buf, 108);
new_dir_lock = CreateDir(buf);
if(new_dir_lock)
UnLock(new_dir_lock);
// create subdirectory trees
{
BPTR sub_old_dir, sub_lock;
BPTR su